| 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391 |
1×
1×
1×
4×
4×
4×
12×
12×
4×
1×
74×
13×
13×
74×
3×
74×
74×
74×
74×
4×
29×
29×
24×
24×
24×
29×
41×
1×
24×
1×
1×
23×
23×
1×
19×
1×
19×
19×
19×
19×
19×
19×
19×
19×
2×
2×
1×
1×
1×
1×
18×
18×
18×
18×
2×
2×
2×
2×
2×
2×
2×
2×
18×
18×
18×
18×
50×
16×
16×
16×
16×
16×
16×
16×
1×
16×
2×
2×
14×
14×
3×
3×
2×
2×
2×
12×
1×
1×
1×
1×
1×
11×
18×
18×
18×
18×
7×
18×
16×
18×
18×
18×
14×
14×
18×
18×
1×
18×
7×
11×
11×
11×
11×
11×
18×
2×
2×
2×
2×
2×
2×
2×
18×
1×
1×
1×
1×
1×
1×
1×
1×
| /**
* ER (Enterprise RIA)
* Copyright 2013 Baidu Inc. All rights reserved.
*
* @ignore
* @file AJAX相关方法
* @author otakustay
*/
define(function (require) {
var TIMESTAMP_PARAM_KEY = '_';
function serializeArray(prefix, array) {
var encodedKey = prefix ? encodeURIComponent(prefix) : '';
var encoded = [];
for (var i = 0; i < array.length; i++) {
var item = array[i];
encoded[i] = this.serializeData('', item);
}
return encodedKey ? encodedKey + '=' + encoded.join(',') : encoded.join(',');
}
function serializeData(prefix, data) {
if (arguments.length === 1) {
data = prefix;
prefix = '';
}
if (data == null) {
data = '';
}
var getKey = this.serializeData.getKey;
var encodedKey = prefix ? encodeURIComponent(prefix) : '';
var type = Object.prototype.toString.call(data);
switch (type) {
case '[object Array]':
return this.serializeArray(prefix, data);
case '[object Object]':
var result = [];
for (var name in data) {
var propertyKey = getKey(name, prefix);
var propertyValue = this.serializeData(propertyKey, data[name]);
result.push(propertyValue);
}
return result.join('&');
default:
return encodedKey ? encodedKey + '=' + encodeURIComponent(data) : encodeURIComponent(data);
}
}
serializeData.getKey = function (propertyName, parentKey) {
return parentKey ? parentKey + '.' + propertyName : propertyName;
};
/**
* @class Ajax
*
* Ajax类
*
* 通过`require('er/ajax').Ajax`访问该类构造函数,其中`require('er/ajax')`是该类的全局实例
*
* @extends mini-event.EventTarget
* @constructor
*/
var exports = {};
exports.constructor = function () {
/**
* AJAX钩子
*
* @type {meta.AjaxHook}
*/
this.hooks = {
serializeData: serializeData,
serializeArray: serializeArray
};
/**
* AJAX配置
*
* @type {meta.AjaxOption}
*/
this.config = {
cache: false,
timeout: 0,
charset: ''
};
};
/**
* 发起`XMLHttpRequest`请求
*
* @param {meta.AjaxOption} options 相关配置
* @return {meta.FakeXHR}
*/
exports.request = function (options) {
if (typeof this.hooks.beforeExecute === 'function') {
this.hooks.beforeExecute(options);
}
var assert = require('./assert');
assert.hasProperty(options, 'url', 'url property is required');
var defaults = {
method: 'POST',
data: {},
cache: this.config.cache,
timeout: this.config.timeout,
charset: this.config.charset
};
var util = require('./util');
options = util.mix(defaults, options);
var Deferred = require('./Deferred');
var requesting = new Deferred();
if (typeof this.hooks.beforeCreate === 'function') {
var canceled = this.hooks.beforeCreate(options, requesting);
if (canceled === true) {
var fakeXHR = requesting.promise;
fakeXHR.abort = function () {};
fakeXHR.setRequestHeader = function () {};
return fakeXHR;
}
}
var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new window.ActiveXObject('Microsoft.XMLHTTP');
util.mix(xhr, options.xhrFields);
var fakeXHR = requesting.promise;
var xhrWrapper = {
abort: function abort() {
// 有些浏览器`abort()`就会把`readyState`变成4,
// 这就会导致进入处理函数变成**resolved**状态,
// 因此事先去掉处理函数,然后直接进入**rejected**状态
xhr.onreadystatechange = null;
try {
xhr.abort();
} catch (ex) {}
Iif (!fakeXHR.status) {
fakeXHR.status = 0;
}
fakeXHR.readyState = xhr.readyState;
fakeXHR.responseText = '';
fakeXHR.responseXML = '';
requesting.reject(fakeXHR);
},
setRequestHeader: function setRequestHeader(name, value) {
xhr.setRequestHeader(name, value);
},
getAllResponseHeaders: function getAllResponseHeaders() {
return xhr.getAllResponseHeaders();
},
getResponseHeader: function getResponseHeader(name) {
return xhr.getResponseHeader(name);
},
getRequestOption: function getRequestOption(name) {
return options[name];
}
};
util.mix(fakeXHR, xhrWrapper);
var eventObject = { xhr: fakeXHR, options: options };
fakeXHR.then(
/**
* @event done
*
* 任意一个请求成功时触发
*
* @param {meta.AjaxOption} options 请求的配置信息
* @param {meta.FakeXHR} xhr 请求对象
*/
util.bind(this.fire, this, 'done', eventObject),
/**
* @event fail
*
* 任意一个请求失败时触发
*
* @param {meta.FakeXHR} xhr 请求对象
* @param {meta.AjaxOption} options 请求的配置信息
*/
util.bind(this.fire, this, 'fail', eventObject));
var processRequestStatus = function processRequestStatus() {
if (xhr.readyState === 4) {
var status = fakeXHR.status || xhr.status;
// IE9会把204状态码变成1223
Iif (status === 1223) {
status = 204;
}
fakeXHR.status = fakeXHR.status || status;
fakeXHR.readyState = xhr.readyState;
fakeXHR.responseText = xhr.responseText;
fakeXHR.responseXML = xhr.responseXML;
if (typeof this.hooks.afterReceive === 'function') {
this.hooks.afterReceive(fakeXHR, options);
}
// 如果请求不成功,也就不用再分解数据了,直接丢回去就好
if (status < 200 || status >= 300 && status !== 304) {
requesting.reject(fakeXHR);
return;
}
var data = xhr.responseText;
if (options.dataType === 'json') {
try {
data = util.parseJSON(data);
} catch (ex) {
// 服务器返回的数据不符合JSON格式,认为请求失败
fakeXHR.error = ex;
requesting.reject(fakeXHR);
return;
}
}
if (typeof this.hooks.afterParse === 'function') {
try {
data = this.hooks.afterParse(data, fakeXHR, options);
} catch (ex) {
fakeXHR.error = ex;
requesting.reject(fakeXHR);
return;
}
}
// 数据处理成功后,进行回调
requesting.resolve(data);
}
};
xhr.onreadystatechange = util.bind(processRequestStatus, this);
var method = options.method.toUpperCase();
var data = {};
if (method === 'GET') {
util.mix(data, options.data);
}
if (options.cache === false) {
data[TIMESTAMP_PARAM_KEY] = +new Date();
}
var query = this.hooks.serializeData('', data, 'application/x-www-form-urlencoded');
var url = options.url;
if (query) {
var delimiter = url.indexOf('?') >= 0 ? '&' : '?';
url += delimiter + query;
}
xhr.open(method, url, true);
if (typeof this.hooks.beforeSend === 'function') {
this.hooks.beforeSend(fakeXHR, options);
}
if (method === 'GET') {
xhr.send();
} else {
var contentType = options.contentType || 'application/x-www-form-urlencoded';
var query = this.hooks.serializeData('', options.data, contentType, fakeXHR);
Iif (options.charset) {
contentType += ';charset=' + options.charset;
}
xhr.setRequestHeader('Content-Type', contentType);
xhr.send(query);
}
if (options.timeout > 0) {
var notifyTimeout = function notifyTimeout() {
/**
* @event timeout
*
* 任意一个请求成功时触发,
* 在此事件后会再触发一次{@link Ajax#fail}事件
*
* @param {meta.FakeXHR} xhr 请求对象
* @param {meta.AjaxOption} options 请求的配置信息
*/
this.fire('timeout', { xhr: fakeXHR, options: options });
fakeXHR.status = 408; // HTTP 408: Request Timeout
fakeXHR.abort();
};
var tick = setTimeout(util.bind(notifyTimeout, this), options.timeout);
fakeXHR.ensure(function () {
clearTimeout(tick);
});
}
return fakeXHR;
};
/**
* 发起一个`GET`请求
*
* @param {string} url 请求的地址
* @param {Object} [data] 请求的数据
* @param {boolean} [cache] 决定是否允许缓存
* @return {meta.FakeXHR}
*/
exports.get = function (url, data, cache) {
var options = {
method: 'GET',
url: url,
data: data,
cache: cache || this.config.cache
};
return this.request(options);
};
/**
* 发起一个`GET`请求并获取JSON数据
*
* @param {string} url 请求的地址
* @param {Object} [data] 请求的数据
* @param {boolean} [cache] 决定是否允许缓存
* @return {meta.FakeXHR}
*/
exports.getJSON = function (url, data, cache) {
var options = {
method: 'GET',
url: url,
data: data,
dataType: 'json',
cache: cache || this.config.cache
};
return this.request(options);
};
/**
* 发起一个`POST`请求
*
* @param {string} url 请求的地址
* @param {Object} [data] 请求的数据
* @param {string} [dataType="json"] 指定响应的数据格式
* @return {meta.FakeXHR}
*/
exports.post = function (url, data, dataType) {
var options = {
method: 'POST',
url: url,
data: data,
dataType: dataType || 'json'
};
return this.request(options);
};
/**
* 发送一个日志请求,该请求只负责发出,不负责保证送达,且不支持回调函数
*
* @param {string} url 发送的目标URL
* @param {Object} [data] 额外添加的参数
*/
exports.log = function (url, data) {
var img = new Image();
var pool = window.ER_LOG_POOL || (window.ER_LOG_POOL = {});
var id = +new Date();
pool[id] = img;
img.onload = img.onerror = img.onabort = function () {
// 如果这个img很不幸正好加载了一个存在的资源,又是个gif动画,
// 则在gif动画播放过程中,img会多次触发onload,因此一定要清空
img.onload = img.onerror = img.onabort = null;
pool[id] = null;
// 下面这句非常重要,
// new Image创建的是DOM,
// DOM的事件中形成闭包环引用DOM是典型的内存泄露,
// 因此这里一定要置为null
img = null;
};
var query = this.hooks.serializeData('', data, 'application/x-www-form-urlencoded');
if (query) {
var delimiter = url.indexOf('?') >= 0 ? ':' : '?';
url += delimiter + query;
}
// 一定要在注册了事件之后再设置src,
// 不然如果图片是读缓存的话,会错过事件处理,
// 最后,对于url最好是添加客户端时间来防止缓存,
// 同时服务器也配合一下传递`Cache-Control: no-cache;`
img.src = url;
};
var Ajax = require('eoo').create(require('fc-mini-event/EventTarget'), exports);
var instance = new Ajax();
instance.Ajax = Ajax;
return instance;
});
//# sourceMappingURL=data:application/json;base64,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QixZQUFJLE9BQU8sT0FBTyxXQUFQLEtBQXVCLE9BQU8sV0FBUCxHQUFxQixFQUFyQixDQUF2QixDQUZvQjtBQUcvQixZQUFJLEtBQUssQ0FBQyxJQUFJLElBQUosRUFBRCxDQUhzQjtBQUkvQixhQUFLLEVBQUwsSUFBVyxHQUFYLENBSitCOztBQU0vQixZQUFJLE1BQUosR0FBYSxJQUFJLE9BQUosR0FBYyxJQUFJLE9BQUosR0FBYyxZQUFZOzs7QUFHakQsZ0JBQUksTUFBSixHQUFhLElBQUksT0FBSixHQUFjLElBQUksT0FBSixHQUFjLElBQWQsQ0FIc0I7O0FBS2pELGlCQUFLLEVBQUwsSUFBVyxJQUFYOzs7Ozs7QUFMaUQsZUFXakQsR0FBTSxJQUFOLENBWGlEO1NBQVosQ0FOVjs7QUFvQi9CLFlBQUksUUFBUSxLQUFLLEtBQUwsQ0FBVyxhQUFYLENBQXlCLEVBQXpCLEVBQTZCLElBQTdCLEVBQW1DLG1DQUFuQyxDQUFSLENBcEIyQjtBQXFCL0IsWUFBSSxLQUFKLEVBQVc7QUFDUCxnQkFBSSxZQUFZLElBQUksT0FBSixDQUFZLEdBQVosS0FBb0IsQ0FBcEIsR0FBd0IsR0FBeEIsR0FBOEIsR0FBOUIsQ0FEVDtBQUVQLG1CQUFPLFlBQVksS0FBWixDQUZBO1NBQVg7Ozs7O0FBckIrQixXQTZCL0IsQ0FBSSxHQUFKLEdBQVUsR0FBVixDQTdCK0I7S0FBckIsQ0F2V0M7O0FBdVlmLFFBQUksT0FBTyxRQUFRLEtBQVIsRUFBZSxNQUFmLENBQXNCLFFBQVEsMkJBQVIsQ0FBdEIsRUFBNEQsT0FBNUQsQ0FBUCxDQXZZVztBQXdZZixRQUFJLFdBQVcsSUFBSSxJQUFKLEVBQVgsQ0F4WVc7QUF5WWYsYUFBUyxJQUFULEdBQWdCLElBQWhCLENBelllO0FBMFlmLFdBQU8sUUFBUCxDQTFZZTtDQUFuQixDQURKIiwiZmlsZSI6ImFqYXguanMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEVSIChFbnRlcnByaXNlIFJJQSlcbiAqIENvcHlyaWdodCAyMDEzIEJhaWR1IEluYy4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBAaWdub3JlXG4gKiBAZmlsZSBBSkFY55u45YWz5pa55rOVXG4gKiBAYXV0aG9yIG90YWt1c3RheVxuICovXG5kZWZpbmUoXG4gICAgZnVuY3Rpb24gKHJlcXVpcmUpIHtcbiAgICAgICAgdmFyIFRJTUVTVEFNUF9QQVJBTV9LRVkgPSAnXyc7XG5cbiAgICAgICAgZnVuY3Rpb24gc2VyaWFsaXplQXJyYXkocHJlZml4LCBhcnJheSkge1xuICAgICAgICAgICAgdmFyIGVuY29kZWRLZXkgPSBwcmVmaXggPyBlbmNvZGVVUklDb21wb25lbnQocHJlZml4KSA6ICcnO1xuICAgICAgICAgICAgdmFyIGVuY29kZWQgPSBbXTtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyYXkubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICB2YXIgaXRlbSA9IGFycmF5W2ldO1xuICAgICAgICAgICAgICAgIGVuY29kZWRbaV0gPSB0aGlzLnNlcmlhbGl6ZURhdGEoJycsIGl0ZW0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGVuY29kZWRLZXlcbiAgICAgICAgICAgICAgICA/IGVuY29kZWRLZXkgKyAnPScgKyBlbmNvZGVkLmpvaW4oJywnKVxuICAgICAgICAgICAgICAgIDogZW5jb2RlZC5qb2luKCcsJyk7XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBzZXJpYWxpemVEYXRhKHByZWZpeCwgZGF0YSkge1xuICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgICAgICBkYXRhID0gcHJlZml4O1xuICAgICAgICAgICAgICAgIHByZWZpeCA9ICcnO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoZGF0YSA9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgZGF0YSA9ICcnO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGdldEtleSA9IHRoaXMuc2VyaWFsaXplRGF0YS5nZXRLZXk7XG4gICAgICAgICAgICB2YXIgZW5jb2RlZEtleSA9IHByZWZpeCA/IGVuY29kZVVSSUNvbXBvbmVudChwcmVmaXgpIDogJyc7XG5cbiAgICAgICAgICAgIHZhciB0eXBlID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGRhdGEpO1xuICAgICAgICAgICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAnW29iamVjdCBBcnJheV0nOlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5zZXJpYWxpemVBcnJheShwcmVmaXgsIGRhdGEpO1xuICAgICAgICAgICAgICAgIGNhc2UgJ1tvYmplY3QgT2JqZWN0XSc6XG4gICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgbmFtZSBpbiBkYXRhKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgcHJvcGVydHlLZXkgPSBnZXRLZXkobmFtZSwgcHJlZml4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwcm9wZXJ0eVZhbHVlID0gdGhpcy5zZXJpYWxpemVEYXRhKHByb3BlcnR5S2V5LCBkYXRhW25hbWVdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKHByb3BlcnR5VmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQuam9pbignJicpO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBlbmNvZGVkS2V5XG4gICAgICAgICAgICAgICAgICAgICAgICA/IGVuY29kZWRLZXkgKyAnPScgKyBlbmNvZGVVUklDb21wb25lbnQoZGF0YSlcbiAgICAgICAgICAgICAgICAgICAgICAgIDogZW5jb2RlVVJJQ29tcG9uZW50KGRhdGEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgc2VyaWFsaXplRGF0YS5nZXRLZXkgPSBmdW5jdGlvbiAocHJvcGVydHlOYW1lLCBwYXJlbnRLZXkpIHtcbiAgICAgICAgICAgIHJldHVybiBwYXJlbnRLZXkgPyBwYXJlbnRLZXkgKyAnLicgKyBwcm9wZXJ0eU5hbWUgOiBwcm9wZXJ0eU5hbWU7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEBjbGFzcyBBamF4XG4gICAgICAgICAqXG4gICAgICAgICAqIEFqYXjnsbtcbiAgICAgICAgICpcbiAgICAgICAgICog6YCa6L+HYHJlcXVpcmUoJ2VyL2FqYXgnKS5BamF4YOiuv+mXruivpeexu+aehOmAoOWHveaVsO+8jOWFtuS4rWByZXF1aXJlKCdlci9hamF4Jylg5piv6K+l57G755qE5YWo5bGA5a6e5L6LXG4gICAgICAgICAqXG4gICAgICAgICAqIEBleHRlbmRzIG1pbmktZXZlbnQuRXZlbnRUYXJnZXRcbiAgICAgICAgICogQGNvbnN0cnVjdG9yXG4gICAgICAgICAqL1xuICAgICAgICB2YXIgZXhwb3J0cyA9IHt9O1xuICAgICAgICBleHBvcnRzLmNvbnN0cnVjdG9yID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBBSkFY6ZKp5a2QXG4gICAgICAgICAgICAgKlxuICAgICAgICAgICAgICogQHR5cGUge21ldGEuQWpheEhvb2t9XG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIHRoaXMuaG9va3MgPSB7XG4gICAgICAgICAgICAgICAgc2VyaWFsaXplRGF0YTogc2VyaWFsaXplRGF0YSxcbiAgICAgICAgICAgICAgICBzZXJpYWxpemVBcnJheTogc2VyaWFsaXplQXJyYXlcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogQUpBWOmFjee9rlxuICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAqIEB0eXBlIHttZXRhLkFqYXhPcHRpb259XG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIHRoaXMuY29uZmlnID0ge1xuICAgICAgICAgICAgICAgIGNhY2hlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICB0aW1lb3V0OiAwLFxuICAgICAgICAgICAgICAgIGNoYXJzZXQ6ICcnXG4gICAgICAgICAgICB9O1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiDlj5HotbdgWE1MSHR0cFJlcXVlc3Rg6K+35rGCXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB7bWV0YS5BamF4T3B0aW9ufSBvcHRpb25zIOebuOWFs+mFjee9rlxuICAgICAgICAgKiBAcmV0dXJuIHttZXRhLkZha2VYSFJ9XG4gICAgICAgICAqL1xuICAgICAgICBleHBvcnRzLnJlcXVlc3QgPSBmdW5jdGlvbiAob3B0aW9ucykge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiB0aGlzLmhvb2tzLmJlZm9yZUV4ZWN1dGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmhvb2tzLmJlZm9yZUV4ZWN1dGUob3B0aW9ucyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBhc3NlcnQgPSByZXF1aXJlKCcuL2Fzc2VydCcpO1xuICAgICAgICAgICAgYXNzZXJ0Lmhhc1Byb3BlcnR5KG9wdGlvbnMsICd1cmwnLCAndXJsIHByb3BlcnR5IGlzIHJlcXVpcmVkJyk7XG5cbiAgICAgICAgICAgIHZhciBkZWZhdWx0cyA9IHtcbiAgICAgICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgICAgICBkYXRhOiB7fSxcbiAgICAgICAgICAgICAgICBjYWNoZTogdGhpcy5jb25maWcuY2FjaGUsXG4gICAgICAgICAgICAgICAgdGltZW91dDogdGhpcy5jb25maWcudGltZW91dCxcbiAgICAgICAgICAgICAgICBjaGFyc2V0OiB0aGlzLmNvbmZpZy5jaGFyc2V0XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgdmFyIHV0aWwgPSByZXF1aXJlKCcuL3V0aWwnKTtcbiAgICAgICAgICAgIG9wdGlvbnMgPSB1dGlsLm1peChkZWZhdWx0cywgb3B0aW9ucyk7XG5cbiAgICAgICAgICAgIHZhciBEZWZlcnJlZCA9IHJlcXVpcmUoJy4vRGVmZXJyZWQnKTtcbiAgICAgICAgICAgIHZhciByZXF1ZXN0aW5nID0gbmV3IERlZmVycmVkKCk7XG5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgdGhpcy5ob29rcy5iZWZvcmVDcmVhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICB2YXIgY2FuY2VsZWQgPSB0aGlzLmhvb2tzLmJlZm9yZUNyZWF0ZShvcHRpb25zLCByZXF1ZXN0aW5nKTtcbiAgICAgICAgICAgICAgICBpZiAoY2FuY2VsZWQgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGZha2VYSFIgPSByZXF1ZXN0aW5nLnByb21pc2U7XG4gICAgICAgICAgICAgICAgICAgIGZha2VYSFIuYWJvcnQgPSBmdW5jdGlvbiAoKSB7fTtcbiAgICAgICAgICAgICAgICAgICAgZmFrZVhIUi5zZXRSZXF1ZXN0SGVhZGVyID0gZnVuY3Rpb24gKCkge307XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWtlWEhSO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIHhociA9IHdpbmRvdy5YTUxIdHRwUmVxdWVzdFxuICAgICAgICAgICAgICAgID8gbmV3IFhNTEh0dHBSZXF1ZXN0KClcbiAgICAgICAgICAgICAgICA6IG5ldyB3aW5kb3cuQWN0aXZlWE9iamVjdCgnTWljcm9zb2Z0LlhNTEhUVFAnKTtcblxuICAgICAgICAgICAgdXRpbC5taXgoeGhyLCBvcHRpb25zLnhockZpZWxkcyk7XG5cbiAgICAgICAgICAgIHZhciBmYWtlWEhSID0gcmVxdWVzdGluZy5wcm9taXNlO1xuICAgICAgICAgICAgdmFyIHhocldyYXBwZXIgPSB7XG4gICAgICAgICAgICAgICAgYWJvcnQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8g5pyJ5Lqb5rWP6KeI5ZmoYGFib3J0KClg5bCx5Lya5oqKYHJlYWR5U3RhdGVg5Y+Y5oiQNO+8jFxuICAgICAgICAgICAgICAgICAgICAvLyDov5nlsLHkvJrlr7zoh7Tov5vlhaXlpITnkIblh73mlbDlj5jmiJAqKnJlc29sdmVkKirnirbmgIHvvIxcbiAgICAgICAgICAgICAgICAgICAgLy8g5Zug5q2k5LqL5YWI5Y675o6J5aSE55CG5Ye95pWw77yM54S25ZCO55u05o6l6L+b5YWlKipyZWplY3RlZCoq54q25oCBXG4gICAgICAgICAgICAgICAgICAgIHhoci5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgeGhyLmFib3J0KCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKGV4KSB7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKCFmYWtlWEhSLnN0YXR1cykge1xuICAgICAgICAgICAgICAgICAgICAgICAgZmFrZVhIUi5zdGF0dXMgPSAwO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGZha2VYSFIucmVhZHlTdGF0ZSA9IHhoci5yZWFkeVN0YXRlO1xuICAgICAgICAgICAgICAgICAgICBmYWtlWEhSLnJlc3BvbnNlVGV4dCA9ICcnO1xuICAgICAgICAgICAgICAgICAgICBmYWtlWEhSLnJlc3BvbnNlWE1MID0gJyc7XG4gICAgICAgICAgICAgICAgICAgIHJlcXVlc3RpbmcucmVqZWN0KGZha2VYSFIpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgc2V0UmVxdWVzdEhlYWRlcjogZnVuY3Rpb24gKG5hbWUsIHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKG5hbWUsIHZhbHVlKTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGdldEFsbFJlc3BvbnNlSGVhZGVyczogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4geGhyLmdldEFsbFJlc3BvbnNlSGVhZGVycygpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZ2V0UmVzcG9uc2VIZWFkZXI6IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB4aHIuZ2V0UmVzcG9uc2VIZWFkZXIobmFtZSk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBnZXRSZXF1ZXN0T3B0aW9uOiBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gb3B0aW9uc1tuYW1lXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgdXRpbC5taXgoZmFrZVhIUiwgeGhyV3JhcHBlcik7XG5cbiAgICAgICAgICAgIHZhciBldmVudE9iamVjdCA9IHsgeGhyOiBmYWtlWEhSLCBvcHRpb25zOiBvcHRpb25zIH07XG4gICAgICAgICAgICBmYWtlWEhSLnRoZW4oXG4gICAgICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgICAgICogQGV2ZW50IGRvbmVcbiAgICAgICAgICAgICAgICAgKlxuICAgICAgICAgICAgICAgICAqIOS7u+aEj+S4gOS4quivt+axguaIkOWKn+aXtuinpuWPkVxuICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIHttZXRhLkFqYXhPcHRpb259IG9wdGlvbnMg6K+35rGC55qE6YWN572u5L+h5oGvXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIHttZXRhLkZha2VYSFJ9IHhociDor7fmsYLlr7nosaFcbiAgICAgICAgICAgICAgICAgKi9cbiAgICAgICAgICAgICAgICB1dGlsLmJpbmQodGhpcy5maXJlLCB0aGlzLCAnZG9uZScsIGV2ZW50T2JqZWN0KSxcbiAgICAgICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAgICAgKiBAZXZlbnQgZmFpbFxuICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICog5Lu75oSP5LiA5Liq6K+35rGC5aSx6LSl5pe26Kem5Y+RXG4gICAgICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0ge21ldGEuRmFrZVhIUn0geGhyIOivt+axguWvueixoVxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSB7bWV0YS5BamF4T3B0aW9ufSBvcHRpb25zIOivt+axgueahOmFjee9ruS/oeaBr1xuICAgICAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgICAgIHV0aWwuYmluZCh0aGlzLmZpcmUsIHRoaXMsICdmYWlsJywgZXZlbnRPYmplY3QpXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICB2YXIgcHJvY2Vzc1JlcXVlc3RTdGF0dXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgaWYgKHhoci5yZWFkeVN0YXRlID09PSA0KSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBzdGF0dXMgPSBmYWtlWEhSLnN0YXR1cyB8fCB4aHIuc3RhdHVzO1xuICAgICAgICAgICAgICAgICAgICAvLyBJRTnkvJrmiooyMDTnirbmgIHnoIHlj5jmiJAxMjIzXG4gICAgICAgICAgICAgICAgICAgIGlmIChzdGF0dXMgPT09IDEyMjMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1cyA9IDIwNDtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGZha2VYSFIuc3RhdHVzID0gZmFrZVhIUi5zdGF0dXMgfHwgc3RhdHVzO1xuICAgICAgICAgICAgICAgICAgICBmYWtlWEhSLnJlYWR5U3RhdGUgPSB4aHIucmVhZHlTdGF0ZTtcbiAgICAgICAgICAgICAgICAgICAgZmFrZVhIUi5yZXNwb25zZVRleHQgPSB4aHIucmVzcG9uc2VUZXh0O1xuICAgICAgICAgICAgICAgICAgICBmYWtlWEhSLnJlc3BvbnNlWE1MID0geGhyLnJlc3BvbnNlWE1MO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdGhpcy5ob29rcy5hZnRlclJlY2VpdmUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaG9va3MuYWZ0ZXJSZWNlaXZlKGZha2VYSFIsIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgLy8g5aaC5p6c6K+35rGC5LiN5oiQ5Yqf77yM5Lmf5bCx5LiN55So5YaN5YiG6Kej5pWw5o2u5LqG77yM55u05o6l5Lii5Zue5Y675bCx5aW9XG4gICAgICAgICAgICAgICAgICAgIGlmIChzdGF0dXMgPCAyMDAgfHwgKHN0YXR1cyA+PSAzMDAgJiYgc3RhdHVzICE9PSAzMDQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0aW5nLnJlamVjdChmYWtlWEhSKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIHZhciBkYXRhID0geGhyLnJlc3BvbnNlVGV4dDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuZGF0YVR5cGUgPT09ICdqc29uJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gdXRpbC5wYXJzZUpTT04oZGF0YSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXRjaCAoZXgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyDmnI3liqHlmajov5Tlm57nmoTmlbDmja7kuI3nrKblkIhKU09O5qC85byP77yM6K6k5Li66K+35rGC5aSx6LSlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFrZVhIUi5lcnJvciA9IGV4O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3RpbmcucmVqZWN0KGZha2VYSFIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdGhpcy5ob29rcy5hZnRlclBhcnNlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSB0aGlzLmhvb2tzLmFmdGVyUGFyc2UoZGF0YSwgZmFrZVhIUiwgb3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXRjaCAoZXgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWtlWEhSLmVycm9yID0gZXg7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdGluZy5yZWplY3QoZmFrZVhIUik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgLy8g5pWw5o2u5aSE55CG5oiQ5Yqf5ZCO77yM6L+b6KGM5Zue6LCDXG4gICAgICAgICAgICAgICAgICAgIHJlcXVlc3RpbmcucmVzb2x2ZShkYXRhKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB4aHIub25yZWFkeXN0YXRlY2hhbmdlID0gdXRpbC5iaW5kKHByb2Nlc3NSZXF1ZXN0U3RhdHVzLCB0aGlzKTtcblxuICAgICAgICAgICAgdmFyIG1ldGhvZCA9IG9wdGlvbnMubWV0aG9kLnRvVXBwZXJDYXNlKCk7XG4gICAgICAgICAgICB2YXIgZGF0YSA9IHt9O1xuICAgICAgICAgICAgaWYgKG1ldGhvZCA9PT0gJ0dFVCcpIHtcbiAgICAgICAgICAgICAgICB1dGlsLm1peChkYXRhLCBvcHRpb25zLmRhdGEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG9wdGlvbnMuY2FjaGUgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgZGF0YVtUSU1FU1RBTVBfUEFSQU1fS0VZXSA9ICtuZXcgRGF0ZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIHF1ZXJ5ID0gdGhpcy5ob29rcy5zZXJpYWxpemVEYXRhKCcnLCBkYXRhLCAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJyk7XG4gICAgICAgICAgICB2YXIgdXJsID0gb3B0aW9ucy51cmw7XG4gICAgICAgICAgICBpZiAocXVlcnkpIHtcbiAgICAgICAgICAgICAgICB2YXIgZGVsaW1pdGVyID0gdXJsLmluZGV4T2YoJz8nKSA+PSAwID8gJyYnIDogJz8nO1xuICAgICAgICAgICAgICAgIHVybCArPSBkZWxpbWl0ZXIgKyBxdWVyeTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgeGhyLm9wZW4obWV0aG9kLCB1cmwsIHRydWUpO1xuXG4gICAgICAgICAgICBpZiAodHlwZW9mIHRoaXMuaG9va3MuYmVmb3JlU2VuZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgIHRoaXMuaG9va3MuYmVmb3JlU2VuZChmYWtlWEhSLCBvcHRpb25zKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKG1ldGhvZCA9PT0gJ0dFVCcpIHtcbiAgICAgICAgICAgICAgICB4aHIuc2VuZCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdmFyIGNvbnRlbnRUeXBlID0gb3B0aW9ucy5jb250ZW50VHlwZSB8fCAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJztcbiAgICAgICAgICAgICAgICB2YXIgcXVlcnkgPSB0aGlzLmhvb2tzLnNlcmlhbGl6ZURhdGEoJycsIG9wdGlvbnMuZGF0YSwgY29udGVudFR5cGUsIGZha2VYSFIpO1xuICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLmNoYXJzZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29udGVudFR5cGUgKz0gJztjaGFyc2V0PScgKyBvcHRpb25zLmNoYXJzZXQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKCdDb250ZW50LVR5cGUnLCBjb250ZW50VHlwZSk7XG4gICAgICAgICAgICAgICAgeGhyLnNlbmQocXVlcnkpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAob3B0aW9ucy50aW1lb3V0ID4gMCkge1xuICAgICAgICAgICAgICAgIHZhciBub3RpZnlUaW1lb3V0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAgICAgICAgICogQGV2ZW50IHRpbWVvdXRcbiAgICAgICAgICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAgICAgICAgICog5Lu75oSP5LiA5Liq6K+35rGC5oiQ5Yqf5pe26Kem5Y+R77yMXG4gICAgICAgICAgICAgICAgICAgICAqIOWcqOatpOS6i+S7tuWQjuS8muWGjeinpuWPkeS4gOasoXtAbGluayBBamF4I2ZhaWx95LqL5Lu2XG4gICAgICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICAgICAqIEBwYXJhbSB7bWV0YS5GYWtlWEhSfSB4aHIg6K+35rGC5a+56LGhXG4gICAgICAgICAgICAgICAgICAgICAqIEBwYXJhbSB7bWV0YS5BamF4T3B0aW9ufSBvcHRpb25zIOivt+axgueahOmFjee9ruS/oeaBr1xuICAgICAgICAgICAgICAgICAgICAgKi9cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5maXJlKFxuICAgICAgICAgICAgICAgICAgICAgICAgJ3RpbWVvdXQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgeyB4aHI6IGZha2VYSFIsIG9wdGlvbnM6IG9wdGlvbnMgfVxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICBmYWtlWEhSLnN0YXR1cyA9IDQwODsgLy8gSFRUUCA0MDg6IFJlcXVlc3QgVGltZW91dFxuICAgICAgICAgICAgICAgICAgICBmYWtlWEhSLmFib3J0KCk7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB2YXIgdGljayA9IHNldFRpbWVvdXQodXRpbC5iaW5kKG5vdGlmeVRpbWVvdXQsIHRoaXMpLCBvcHRpb25zLnRpbWVvdXQpO1xuICAgICAgICAgICAgICAgIGZha2VYSFIuZW5zdXJlKGZ1bmN0aW9uICgpIHsgY2xlYXJUaW1lb3V0KHRpY2spOyB9KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIGZha2VYSFI7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIOWPkei1t+S4gOS4qmBHRVRg6K+35rGCXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSB1cmwg6K+35rGC55qE5Zyw5Z2AXG4gICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbZGF0YV0g6K+35rGC55qE5pWw5o2uXG4gICAgICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2NhY2hlXSDlhrPlrprmmK/lkKblhYHorrjnvJPlrZhcbiAgICAgICAgICogQHJldHVybiB7bWV0YS5GYWtlWEhSfVxuICAgICAgICAgKi9cbiAgICAgICAgZXhwb3J0cy5nZXQgPSBmdW5jdGlvbiAodXJsLCBkYXRhLCBjYWNoZSkge1xuICAgICAgICAgICAgdmFyIG9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgbWV0aG9kOiAnR0VUJyxcbiAgICAgICAgICAgICAgICB1cmw6IHVybCxcbiAgICAgICAgICAgICAgICBkYXRhOiBkYXRhLFxuICAgICAgICAgICAgICAgIGNhY2hlOiBjYWNoZSB8fCB0aGlzLmNvbmZpZy5jYWNoZVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnJlcXVlc3Qob3B0aW9ucyk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIOWPkei1t+S4gOS4qmBHRVRg6K+35rGC5bm26I635Y+WSlNPTuaVsOaNrlxuICAgICAgICAgKlxuICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gdXJsIOivt+axgueahOWcsOWdgFxuICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gW2RhdGFdIOivt+axgueahOaVsOaNrlxuICAgICAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtjYWNoZV0g5Yaz5a6a5piv5ZCm5YWB6K6457yT5a2YXG4gICAgICAgICAqIEByZXR1cm4ge21ldGEuRmFrZVhIUn1cbiAgICAgICAgICovXG4gICAgICAgIGV4cG9ydHMuZ2V0SlNPTiA9IGZ1bmN0aW9uICh1cmwsIGRhdGEsIGNhY2hlKSB7XG4gICAgICAgICAgICB2YXIgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICBtZXRob2Q6ICdHRVQnLFxuICAgICAgICAgICAgICAgIHVybDogdXJsLFxuICAgICAgICAgICAgICAgIGRhdGE6IGRhdGEsXG4gICAgICAgICAgICAgICAgZGF0YVR5cGU6ICdqc29uJyxcbiAgICAgICAgICAgICAgICBjYWNoZTogY2FjaGUgfHwgdGhpcy5jb25maWcuY2FjaGVcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5yZXF1ZXN0KG9wdGlvbnMpO1xuICAgICAgICB9O1xuXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIOWPkei1t+S4gOS4qmBQT1NUYOivt+axglxuICAgICAgICAgKlxuICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gdXJsIOivt+axgueahOWcsOWdgFxuICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gW2RhdGFdIOivt+axgueahOaVsOaNrlxuICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gW2RhdGFUeXBlPVwianNvblwiXSDmjIflrprlk43lupTnmoTmlbDmja7moLzlvI9cbiAgICAgICAgICogQHJldHVybiB7bWV0YS5GYWtlWEhSfVxuICAgICAgICAgKi9cbiAgICAgICAgZXhwb3J0cy5wb3N0ID0gZnVuY3Rpb24gKHVybCwgZGF0YSwgZGF0YVR5cGUpIHtcbiAgICAgICAgICAgIHZhciBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgICAgIHVybDogdXJsLFxuICAgICAgICAgICAgICAgIGRhdGE6IGRhdGEsXG4gICAgICAgICAgICAgICAgZGF0YVR5cGU6IGRhdGFUeXBlIHx8ICdqc29uJ1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnJlcXVlc3Qob3B0aW9ucyk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIOWPkemAgeS4gOS4quaXpeW/l+ivt+axgu+8jOivpeivt+axguWPqui0n+i0o+WPkeWHuu+8jOS4jei0n+i0o+S/neivgemAgei+vu+8jOS4lOS4jeaUr+aMgeWbnuiwg+WHveaVsFxuICAgICAgICAgKlxuICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gdXJsIOWPkemAgeeahOebruagh1VSTFxuICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gW2RhdGFdIOmineWklua3u+WKoOeahOWPguaVsFxuICAgICAgICAgKi9cbiAgICAgICAgZXhwb3J0cy5sb2cgPSBmdW5jdGlvbiAodXJsLCBkYXRhKSB7XG4gICAgICAgICAgICB2YXIgaW1nID0gbmV3IEltYWdlKCk7XG4gICAgICAgICAgICB2YXIgcG9vbCA9IHdpbmRvdy5FUl9MT0dfUE9PTCB8fCAod2luZG93LkVSX0xPR19QT09MID0ge30pO1xuICAgICAgICAgICAgdmFyIGlkID0gK25ldyBEYXRlKCk7XG4gICAgICAgICAgICBwb29sW2lkXSA9IGltZztcblxuICAgICAgICAgICAgaW1nLm9ubG9hZCA9IGltZy5vbmVycm9yID0gaW1nLm9uYWJvcnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgLy8g5aaC5p6c6L+Z5LiqaW1n5b6I5LiN5bm45q2j5aW95Yqg6L295LqG5LiA5Liq5a2Y5Zyo55qE6LWE5rqQ77yM5Y+I5piv5LiqZ2lm5Yqo55S777yMXG4gICAgICAgICAgICAgICAgLy8g5YiZ5ZyoZ2lm5Yqo55S75pKt5pS+6L+H56iL5Lit77yMaW1n5Lya5aSa5qyh6Kem5Y+Rb25sb2Fk77yM5Zug5q2k5LiA5a6a6KaB5riF56m6XG4gICAgICAgICAgICAgICAgaW1nLm9ubG9hZCA9IGltZy5vbmVycm9yID0gaW1nLm9uYWJvcnQgPSBudWxsO1xuXG4gICAgICAgICAgICAgICAgcG9vbFtpZF0gPSBudWxsO1xuXG4gICAgICAgICAgICAgICAgLy8g5LiL6Z2i6L+Z5Y+l6Z2e5bi46YeN6KaB77yMXG4gICAgICAgICAgICAgICAgLy8gbmV3IEltYWdl5Yib5bu655qE5pivRE9N77yMXG4gICAgICAgICAgICAgICAgLy8gRE9N55qE5LqL5Lu25Lit5b2i5oiQ6Zet5YyF546v5byV55SoRE9N5piv5YW45Z6L55qE5YaF5a2Y5rOE6Zyy77yMXG4gICAgICAgICAgICAgICAgLy8g5Zug5q2k6L+Z6YeM5LiA5a6a6KaB572u5Li6bnVsbFxuICAgICAgICAgICAgICAgIGltZyA9IG51bGw7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB2YXIgcXVlcnkgPSB0aGlzLmhvb2tzLnNlcmlhbGl6ZURhdGEoJycsIGRhdGEsICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnKTtcbiAgICAgICAgICAgIGlmIChxdWVyeSkge1xuICAgICAgICAgICAgICAgIHZhciBkZWxpbWl0ZXIgPSB1cmwuaW5kZXhPZignPycpID49IDAgPyAnOicgOiAnPyc7XG4gICAgICAgICAgICAgICAgdXJsICs9IGRlbGltaXRlciArIHF1ZXJ5O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8g5LiA5a6a6KaB5Zyo5rOo5YaM5LqG5LqL5Lu25LmL5ZCO5YaN6K6+572uc3Jj77yMXG4gICAgICAgICAgICAvLyDkuI3nhLblpoLmnpzlm77niYfmmK/or7vnvJPlrZjnmoTor53vvIzkvJrplJnov4fkuovku7blpITnkIbvvIxcbiAgICAgICAgICAgIC8vIOacgOWQju+8jOWvueS6jnVybOacgOWlveaYr+a3u+WKoOWuouaIt+err+aXtumXtOadpemYsuatoue8k+WtmO+8jFxuICAgICAgICAgICAgLy8g5ZCM5pe25pyN5Yqh5Zmo5Lmf6YWN5ZCI5LiA5LiL5Lyg6YCSYENhY2hlLUNvbnRyb2w6IG5vLWNhY2hlO2BcbiAgICAgICAgICAgIGltZy5zcmMgPSB1cmw7XG4gICAgICAgIH07XG5cbiAgICAgICAgdmFyIEFqYXggPSByZXF1aXJlKCdlb28nKS5jcmVhdGUocmVxdWlyZSgnZmMtbWluaS1ldmVudC9FdmVudFRhcmdldCcpLCBleHBvcnRzKTtcbiAgICAgICAgdmFyIGluc3RhbmNlID0gbmV3IEFqYXgoKTtcbiAgICAgICAgaW5zdGFuY2UuQWpheCA9IEFqYXg7XG4gICAgICAgIHJldHVybiBpbnN0YW5jZTtcbiAgICB9XG4pO1xuIl19 |